import { LeagueDetail, LeagueMatch, LeaguePlayerRanking } from '@/types/dota'

interface CacheItem<T> {
  data: T
  timestamp: number
  expiresAt: number
}

interface CacheConfig {
  defaultTTL: number // 默认缓存时间（毫秒）
  maxSize: number    // 最大缓存项数
  enablePersistence: boolean // 是否启用持久化
  persistencePrefix: string  // localStorage 前缀
}

class CacheManager {
  private cache = new Map<string, CacheItem<any>>()
  private config: CacheConfig
  private persistenceKeys = new Set<string>() // 跟踪需要持久化的键

  constructor(config: Partial<CacheConfig> = {}) {
    this.config = {
      defaultTTL: 10 * 60 * 1000, // 10分钟
      maxSize: 100,
      enablePersistence: true,
      persistencePrefix: 'dota_league_cache_',
      ...config
    }

    // 初始化时从 localStorage 恢复数据
    if (this.config.enablePersistence && typeof window !== 'undefined') {
      this.loadFromPersistence()
    }

    // 定期清理过期缓存
    this.startCleanupTimer()
  }

  /**
   * 从 localStorage 恢复缓存数据
   */
  private loadFromPersistence(): void {
    try {
      const keys = Object.keys(localStorage).filter(key => 
        key.startsWith(this.config.persistencePrefix)
      )

      for (const storageKey of keys) {
        const cacheKey = storageKey.replace(this.config.persistencePrefix, '')
        const stored = localStorage.getItem(storageKey)
        
        if (stored) {
          const item: CacheItem<any> = JSON.parse(stored)
          
          // 检查是否过期
          if (item.expiresAt > Date.now()) {
            this.cache.set(cacheKey, item)
            this.persistenceKeys.add(cacheKey)
            console.log(`从持久化存储恢复缓存: ${cacheKey}`)
          } else {
            // 清理过期的持久化数据
            localStorage.removeItem(storageKey)
            console.log(`清理过期的持久化缓存: ${cacheKey}`)
          }
        }
      }
    } catch (error) {
      console.error('从持久化存储恢复缓存失败:', error)
    }
  }

  /**
   * 保存到 localStorage
   */
  private saveToPersistence(key: string, item: CacheItem<any>): void {
    if (!this.config.enablePersistence || typeof window === 'undefined') {
      return
    }

    try {
      const storageKey = this.config.persistencePrefix + key
      localStorage.setItem(storageKey, JSON.stringify(item))
      this.persistenceKeys.add(key)
    } catch (error) {
      console.error(`保存缓存到持久化存储失败 (${key}):`, error)
      
      // 如果存储空间不足，尝试清理一些旧数据
      if (error instanceof DOMException && error.code === 22) {
        this.cleanupOldPersistentData()
        // 再次尝试保存
        try {
          const storageKey = this.config.persistencePrefix + key
          localStorage.setItem(storageKey, JSON.stringify(item))
          this.persistenceKeys.add(key)
        } catch (retryError) {
          console.error(`重试保存缓存失败 (${key}):`, retryError)
        }
      }
    }
  }

  /**
   * 从 localStorage 删除
   */
  private removeFromPersistence(key: string): void {
    if (!this.config.enablePersistence || typeof window === 'undefined') {
      return
    }

    try {
      const storageKey = this.config.persistencePrefix + key
      localStorage.removeItem(storageKey)
      this.persistenceKeys.delete(key)
    } catch (error) {
      console.error(`从持久化存储删除缓存失败 (${key}):`, error)
    }
  }

  /**
   * 清理旧的持久化数据
   */
  private cleanupOldPersistentData(): void {
    try {
      const keys = Object.keys(localStorage).filter(key => 
        key.startsWith(this.config.persistencePrefix)
      )

      // 按时间戳排序，删除最旧的数据
      const items = keys.map(storageKey => {
        const stored = localStorage.getItem(storageKey)
        if (stored) {
          try {
            const item = JSON.parse(stored)
            return { storageKey, timestamp: item.timestamp }
          } catch {
            return { storageKey, timestamp: 0 }
          }
        }
        return { storageKey, timestamp: 0 }
      }).sort((a, b) => a.timestamp - b.timestamp)

      // 删除最旧的 25% 数据
      const deleteCount = Math.ceil(items.length * 0.25)
      for (let i = 0; i < deleteCount; i++) {
        localStorage.removeItem(items[i].storageKey)
        const cacheKey = items[i].storageKey.replace(this.config.persistencePrefix, '')
        this.persistenceKeys.delete(cacheKey)
      }

      console.log(`清理了 ${deleteCount} 个旧的持久化缓存项`)
    } catch (error) {
      console.error('清理旧持久化数据失败:', error)
    }
  }

  /**
   * 设置缓存项
   */
  set<T>(key: string, data: T, ttl?: number, persist: boolean = true): void {
    const now = Date.now()
    const expiresAt = now + (ttl || this.config.defaultTTL)
    
    const item: CacheItem<T> = {
      data,
      timestamp: now,
      expiresAt
    }

    // 检查缓存大小限制
    if (this.cache.size >= this.config.maxSize) {
      this.evictOldest()
    }

    this.cache.set(key, item)

    // 保存到持久化存储
    if (persist) {
      this.saveToPersistence(key, item)
    }

    console.log(`缓存已设置: ${key}, TTL: ${ttl || this.config.defaultTTL}ms, 持久化: ${persist}`)
  }

  /**
   * 获取缓存项
   */
  get<T>(key: string): T | null {
    const item = this.cache.get(key)
    
    if (!item) {
      return null
    }

    // 检查是否过期
    if (item.expiresAt <= Date.now()) {
      this.delete(key)
      return null
    }

    return item.data as T
  }

  /**
   * 删除缓存项
   */
  delete(key: string): void {
    this.cache.delete(key)
    this.removeFromPersistence(key)
    console.log(`缓存已删除: ${key}`)
  }

  /**
   * 检查缓存项是否存在且未过期
   */
  has(key: string): boolean {
    const item = this.cache.get(key)
    
    if (!item) {
      return false
    }

    if (item.expiresAt <= Date.now()) {
      this.delete(key)
      return false
    }

    return true
  }

  /**
   * 清空所有缓存
   */
  clear(): void {
    // 清空内存缓存
    this.cache.clear()

    // 清空持久化缓存
    if (this.config.enablePersistence && typeof window !== 'undefined') {
      try {
        const keys = Object.keys(localStorage).filter(key => 
          key.startsWith(this.config.persistencePrefix)
        )
        
        for (const key of keys) {
          localStorage.removeItem(key)
        }
        
        this.persistenceKeys.clear()
        console.log('所有缓存已清空（包括持久化数据）')
      } catch (error) {
        console.error('清空持久化缓存失败:', error)
      }
    }
  }

  /**
   * 驱逐最旧的缓存项
   */
  private evictOldest(): void {
    let oldestKey: string | null = null
    let oldestTimestamp = Date.now()

    for (const [key, item] of this.cache.entries()) {
      if (item.timestamp < oldestTimestamp) {
        oldestTimestamp = item.timestamp
        oldestKey = key
      }
    }

    if (oldestKey) {
      this.delete(oldestKey)
      console.log(`驱逐最旧缓存项: ${oldestKey}`)
    }
  }

  /**
   * 清理过期缓存
   */
  private cleanup(): void {
    const now = Date.now()
    const expiredKeys: string[] = []

    for (const [key, item] of this.cache.entries()) {
      if (item.expiresAt <= now) {
        expiredKeys.push(key)
      }
    }

    for (const key of expiredKeys) {
      this.delete(key)
    }

    if (expiredKeys.length > 0) {
      console.log(`清理了 ${expiredKeys.length} 个过期缓存项`)
    }
  }

  /**
   * 启动清理定时器
   */
  private startCleanupTimer(): void {
    // 每5分钟清理一次过期缓存
    setInterval(() => {
      this.cleanup()
    }, 5 * 60 * 1000)
  }

  /**
   * 获取缓存统计信息
   */
  getStats(): {
    size: number
    maxSize: number
    persistentKeys: number
    memoryUsage: string
  } {
    let memoryUsage = 0
    
    try {
      // 估算内存使用量
      for (const [key, item] of this.cache.entries()) {
        memoryUsage += JSON.stringify({ key, item }).length * 2 // UTF-16 字符占2字节
      }
    } catch {
      memoryUsage = 0
    }

    return {
      size: this.cache.size,
      maxSize: this.config.maxSize,
      persistentKeys: this.persistenceKeys.size,
      memoryUsage: `${(memoryUsage / 1024).toFixed(2)} KB`
    }
  }

  // 联赛相关的缓存方法
  /**
   * 获取缓存的 ETag 和 Last-Modified 信息
   */
  getETagAndLastModified(leagueId: number, type: 'detail' | 'matches' | 'ranking'): { etag?: string; lastModified?: string } | null {
    const key = `league_${leagueId}_${type}_headers`
    return this.get<{ etag?: string; lastModified?: string }>(key)
  }

  /**
   * 设置 ETag 和 Last-Modified 信息
   */
  setETagAndLastModified(leagueId: number, type: 'detail' | 'matches' | 'ranking', headers: { etag?: string; lastModified?: string }): void {
    const key = `league_${leagueId}_${type}_headers`
    this.set(key, headers, this.config.defaultTTL, true)
  }

  /**
   * 获取缓存的比赛数量
   */
  getCachedMatchCount(leagueId: number): number | null {
    const key = `league_${leagueId}_match_count`
    return this.get<number>(key)
  }

  /**
   * 设置缓存的比赛数量
   */
  setCachedMatchCount(leagueId: number, matchCount: number): void {
    const key = `league_${leagueId}_match_count`
    this.set(key, matchCount, this.config.defaultTTL, true) // 持久化存储
  }

  setLeagueDetail(leagueId: number, detail: LeagueDetail): void {
    this.set(`league_detail_${leagueId}`, detail, 15 * 60 * 1000) // 15分钟
  }

  getLeagueDetail(leagueId: number): LeagueDetail | null {
    return this.get<LeagueDetail>(`league_detail_${leagueId}`)
  }

  setLeagueMatches(leagueId: number, matches: LeagueMatch[]): void {
    this.set(`league_matches_${leagueId}`, matches, 10 * 60 * 1000) // 10分钟
  }

  getLeagueMatches(leagueId: number): LeagueMatch[] | null {
    return this.get<LeagueMatch[]>(`league_matches_${leagueId}`)
  }

  setLeagueRanking(leagueId: number, ranking: LeaguePlayerRanking): void {
    this.set(`league_ranking_${leagueId}`, ranking, 30 * 60 * 1000) // 30分钟
  }

  getLeagueRanking(leagueId: number): LeaguePlayerRanking | null {
    return this.get<LeaguePlayerRanking>(`league_ranking_${leagueId}`)
  }

  clearLeagueCache(leagueId: number): void {
    this.delete(`league_detail_${leagueId}`)
    this.delete(`league_matches_${leagueId}`)
    this.delete(`league_ranking_${leagueId}`)
    console.log(`已清除联赛 ${leagueId} 的所有缓存`)
  }

  /**
   * 预热缓存 - 在应用启动时调用
   */
  warmup(): void {
    console.log('缓存管理器预热完成')
    const stats = this.getStats()
    console.log('缓存统计:', stats)
  }

  /**
   * 销毁缓存管理器
   */
  destroy(): void {
    this.cache.clear()
    console.log('缓存管理器已销毁')
  }
}

// 创建全局缓存管理器实例
export const cacheManager = new CacheManager({
  defaultTTL: 10 * 60 * 1000, // 10分钟
  maxSize: 50,
  enablePersistence: true,
  persistencePrefix: 'dota_league_cache_'
})

// 在应用启动时预热缓存
if (typeof window !== 'undefined') {
  // 延迟预热，确保应用完全加载
  setTimeout(() => {
    cacheManager.warmup()
  }, 1000)
}